home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / c / library / bcfamily / source / _heap.cpp next >
Encoding:
C/C++ Source or Header  |  1993-03-20  |  2.7 KB  |  115 lines

  1. //
  2. //      *******************************************************************
  3. //        JdeBP C++ Library Routines          General Public Licence v1.00
  4. //            Copyright (c) 1991,1992     Jonathan de Boyne Pollard
  5. //      *******************************************************************
  6. //
  7. // Place in library : STDCm.LIB
  8. //
  9.  
  10. #define    _MSDOS_SOURCE    1
  11. #include <stddef.h>
  12. #include <stdlib.h>
  13. #include <errno.h>
  14. #include <limits.h>
  15. #include <os2.h>
  16. #include "_malloc.h"
  17. #include "_c0.h"
  18.  
  19.  
  20. union HeapRecord {
  21.     size_t size ;                            // Size of block (inc header)
  22.     union  HeapRecord near *next ;            // Next heap record
  23.     struct FreeHeapRecord {
  24.         struct FreeHeapRecord near *next ;    // Next free record
  25.         struct FreeHeapRecord near *prev ;    // Next free record
  26.     } f ;
  27. } ;
  28.  
  29. struct HeapSegment {
  30.     struct HeapSegment far *next ;        // Next segment in far heap
  31.     size_t segsize ;                    // Size of segment in bytes
  32.     size_t maxsize ;                    // Maximum size in bytes
  33.     union HeapRecord near *first ;        // First in free list
  34.     union HeapRecord near *last ;        // Last in free list
  35.     union HeapRecord near *rover ;        // Roving pointer
  36. } ;
  37.  
  38.  
  39. //
  40. //    Sub-Allocation out of a single segment
  41. //
  42.  
  43. static
  44. union HeapRecord far *
  45. AllocateFromSegment ( struct HeapSegment far *hseg, size_t needed )
  46. {
  47.     if (needed > (hseg->segsize - sizeof(union HeapRecord))
  48.         return 0 ;
  49.  
  50.     needed += sizeof(union HeapRecord) ;
  51.  
  52.     if (hseg->first == 0)
  53.         return CreateSegment(hseg, needed) ;
  54.  
  55.     if (hseg->rover != 0) {
  56.  
  57.         union HeapRecord far *start = hseg->rover ;
  58.  
  59.         do {
  60.  
  61.             register union HeapRecord far *rover = hseg->rover ;
  62.  
  63.             if (rover->size > needed) {
  64.  
  65.                 // Allocate the tail part of the heap record
  66.  
  67.                 union HeapRecord far *old = rover ;
  68.  
  69.                 rover->size -= needed ;
  70.  
  71.                 rover = (union HeapRecord far *)
  72.                             ((unsigned char far *)rover + rover->size) ;
  73.  
  74.                 rover->size = needed ;
  75.                 rover->next = old->next ;
  76.                 old->next = rover ;
  77.  
  78.                 return rover ;
  79.  
  80.             } else if (rover->size == needed) {
  81.  
  82.                 // Pull the heap record off the free list
  83.  
  84.                 if (rover->f.next != rover) {
  85.                     rover->f.next->f.prev = rover->f.prev ;
  86.                     rover->f.prev->f.next = rover->f.next ;
  87.                 } else
  88.                     hseg->rover = 0 ;
  89.  
  90.                 return rover ;
  91.  
  92.             } else
  93.                 hseg->rover = rover->f.next ;
  94.  
  95.         } while (hseg->rover != start) ;
  96.     }
  97.  
  98.     if (hseg->segsize > (hseg->maxsize - needed)
  99.         return 0 ;
  100.  
  101.     union HeapRecord far *append =
  102.         (union HeapRecord far *)(MK_FP(FP_SEG(hseg), hseg->segsize)) ;
  103.  
  104.     USHORT err = DosReallocSeg (FP_SEG(hseg), hseg->segsize += needed) ;
  105.  
  106.     if (err)
  107.         return 0 ;
  108.  
  109.     hseg->last->next = append ;
  110.     append->size = needed ;
  111.     append->next = 0 ;
  112.     hseg->last = append ;
  113.  
  114.     return append ;
  115. }